package com.whccb.apps.office.document.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.xml.security.utils.Base64;

import com.actionsoft.apps.resource.AppContext;
import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.HistoryTaskInstance;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.commons.formfile.model.FormFileModel;
import com.actionsoft.bpms.commons.formfile.model.delegate.FormFile;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.commons.security.ac.constant.ACConst;
import com.actionsoft.bpms.org.cache.UserCache;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.fs.DCContext;
import com.actionsoft.bpms.server.fs.dc.DCProfileManager;
import com.actionsoft.bpms.util.ConsolePrinter;
import com.actionsoft.bpms.util.UUIDGener;
import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.local.api.AppAPI;
import com.actionsoft.sdk.local.api.LogAPI;
import com.actionsoft.sdk.local.api.Logger;
import com.whccb.apps.office.document.ODConstant;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class CMSUtil {

	private static final Logger logger = LogAPI.getLogger(CMSUtil.class);
	
	private static final String sourceAppId = "com.actionsoft.apps.cms";
	private static final String aslp = "aslp://com.actionsoft.apps.cms/createContent";

	public static String createUrlCmsData(UserContext uc, String moduleId, String processInstId, String taskInstId,
			String formDefId, String title, JSONArray attachmentList, List<String> teamIdList, String boname,
			String pdfField, String attfileField, String createrUserID) throws Exception {
		
		String sid = uc.getSessionId();
		AppAPI appAPI = SDK.getAppAPI();
		AppContext cmsApp = appAPI.getAppContext(sourceAppId);
		String cmsBoId = "";
		
		try {
			Map<String, Object> params = new HashMap<>();
			String msgtype = "3";
			params.put("sid", sid);
			params.put("createuser", createrUserID);
			params.put("createtime", DateUtils.format(new Date(), DateUtils.DATETIME_DFT_PATTERN));
			params.put("moduleid", moduleId);
			params.put("title", title);
			params.put("msgtype", msgtype);
			params.put("attachment", attachmentList);

			// 服务地址
			String url = "@getPdfPreviewUrl(@sid," + processInstId + "," + taskInstId + "," + formDefId + "," + boname
					+ "," + pdfField + "," + attfileField + ")";
			// String url =
			// "@portalUrl/r/w?sid=@sid&cmd=com.whccb.apps.office.document.gw_cms_page&processInstId="
			// + processInstId
			// + "&taskInstId="
			// + taskInstId
			// + "&formDefId=" + formDefId;
			params.put("outurl", url);
			
			ResponseObject ro = appAPI.callASLP(cmsApp, aslp, params);
			// {"data":{"boId":"31c9e42e-487f-4787-9a94-b49e82f41211"},"msg":"","id":":RO;","result":"ok"}

			if (ro!=null && ro.isOk()) {
				String processdefid = SDK.getProcessAPI().getInstanceById(processInstId).getProcessDefId();
				// 增加访问权限
				cmsBoId = ro.get("boId") + "";
				logger.info("体系文件，createUrlCmsData，processdefid="+processdefid+"，cmsBoId="+cmsBoId);
				
				// 如果为体系文件发布流程走另一套权限设定
				if (StringUtils.isNotBlank(processdefid) && ODConstant.TXWJ_PROCESSDEFID.equals(processdefid)) {
					
					String level = SDK.getBOAPI().getByProcess(boname, processInstId, "REG_LEVEL_DICT") + "";
					logger.info("体系文件,createUrlCmsData,LEVEL----level="+level+",userid="+createrUserID);
					
					// 判断发送的体系文件是否05分行管辖行层级制度
					if (StringUtils.isNotBlank(level) && "05".equals(level)) {
						List<String> deptlist = new ArrayList<>();
						String deptoneid = SDK.getRuleAPI().executeAtScript("@getAwsDeptIdByOuterId(@getUserExtInfo(" + createrUserID + ",HRFIRSTORGID))");
						
						if (StringUtils.isNotBlank(deptoneid)) {
							deptlist.add(deptoneid);
						}
						
						deptlist.add(UserCache.getModel(createrUserID).getDepartmentId());
						addCMSPermi(cmsBoId, deptlist, ACConst.ASSIGN_DEPARTMENT);
						logger.info("体系文件,createUrlCmsData,deptid="+deptoneid);
					} else {
						return cmsBoId;
					}

				} else {
					// 增加群组访问权限
					addCMSPermi(cmsBoId, teamIdList, ACConst.ASSIGN_TEAM);
				}

				// 找出流程审批人增加权限
				if (CollectionUtils.isNotEmpty(teamIdList)) {
					
					List<String> action = new ArrayList<>();
					
					/**
					 * 获取流程实例
					 */
					ProcessInstance pInstance = SDK.getProcessQueryAPI().detailById(processInstId);
					
					if (pInstance!=null && pInstance.isExistSubProcess()) {
						
						/**
						 * 获取子流程，将子流程中的审批人员加入到列表中
						 */
						List<ProcessInstance> sublist = SDK.getProcessQueryAPI().parentProcessInstId(processInstId).list();
						if (CollectionUtils.isNotEmpty(sublist)) {
							for (ProcessInstance pi : sublist) {
								List<HistoryTaskInstance> subtaskInstances = SDK.getHistoryTaskQueryAPI().processInstId(pi.getId()).userTask().list();
								for (HistoryTaskInstance ht : subtaskInstances) {
									if (!action.contains(ht.getTarget())) {
										action.add(ht.getTarget());
									}
								}
							}
						}
					}
					logger.info("体系文件,createUrlCmsData,子流程中的审批人员已加入！");
					/**
					 * 将主流程的的人员加入到列表中
					 */
					List<HistoryTaskInstance> taskInstances = SDK.getHistoryTaskQueryAPI().processInstId(processInstId).userTask().list();
					for (HistoryTaskInstance ht : taskInstances) {
						if (!action.contains(ht.getTarget())) {
							action.add(ht.getTarget());
						}
					}
					logger.info("体系文件,createUrlCmsData,主流程中的审批人员已加入！");
					action.add("admin");
					// String cmsBoId = ro.get("boId") + "";
					// ConsolePrinter.info("特殊授权数组----" + action.size());
					//String[] acs = action.toArray(new String[action.size()]);
					addCMSPermi(cmsBoId, action, ACConst.ASSIGN_USER);
				}
			}

		} catch (Exception e) {
			logger.error("体系文件，createUrlCmsData方法异常！", e);
			throw new Exception("体系文件，createUrlCmsData方法异常！");
		}
		return cmsBoId;
	}
	
	/**
	 * 获取附件
	 * @param boId 模型id
	 * @param officeField 正文字段id
	 * @param attfileField 附件字段id
	 * @return
	 * @throws Exception 
	 */
	public static JSONArray getAttach(String boId, String officeField, String attfileField) throws Exception {
		JSONArray attachmentList = new JSONArray();
		// 先处理正文
		// 构建iweboffice写的dc
		if (StringUtils.isNotBlank(officeField)) {
			
			List<FormFile> webOfficeFormFiles = SDK.getBOAPI().getFiles(boId, officeField);// 正文
			
			if (CollectionUtils.isNotEmpty(webOfficeFormFiles)) {
				
				DCContext webOfficeDc = IWebOfficeUtil.getWebOfficeDc(webOfficeFormFiles.get(0));
				
				if (webOfficeDc != null) {
					JSONObject attachmentMap = new JSONObject();
					attachmentMap.put("fileName", webOfficeDc.getFileName());
					attachmentMap.put("fileoldname", webOfficeDc.getFileName());
					InputStream is = null;
					try {
						is = SDK.getDCAPI().read(webOfficeDc);
						ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
						byte[] buf = new byte[1024];
						int rc = 0;
						while ((rc = is.read(buf, 0, 1024)) > 0) {
							swapStream.write(buf, 0, rc);
						}
						byte[] bytedata = swapStream.toByteArray();

						attachmentMap.put("data", new String(Base64.encode(bytedata)));
						attachmentList.add(attachmentMap);
					} catch (Exception e) {
						logger.error("getAttach方法正文部分异常！", e);
						throw new Exception("getAttach方法正文部分异常！");
					} finally {
						try {
							is.close();
						} catch (Exception e) {
							logger.error("getAttach方法关闭正文IO流异常！", e);
							throw new IOException("getAttach方法关闭正文IO流异常！");
						}
					}
				}
			}
		}
		
		/**
		 * 处理附件部分
		 */
		if (StringUtils.isNotBlank(attfileField)) {
			List<FormFile> formFiles = SDK.getBOAPI().getFiles(boId, attfileField);
			
			if (CollectionUtils.isNotEmpty(formFiles)) {
				for (FormFile formFile : formFiles) {
					if (formFile != null) {
						JSONObject attachmentMap = new JSONObject();
						attachmentMap.put("fileName", formFile.getFileName());
						attachmentMap.put("fileoldname", formFile.getFileName());
						InputStream is = null;
						try {
							is = SDK.getBOAPI().getFile(formFile.getId());
							ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
							byte[] buf = new byte[1024];
							int rc = 0;
							while ((rc = is.read(buf, 0, 1024)) > 0) {
								swapStream.write(buf, 0, rc);
							}
							byte[] bytedata = swapStream.toByteArray();

							attachmentMap.put("data", new String(Base64.encode(bytedata)));
							attachmentList.add(attachmentMap);
						} catch (Exception e) {
							logger.error("getAttach方法,附件部分异常！", e);
							throw new Exception("getAttach方法,附件部分异常！");
						} finally {
							try {
								is.close();
							} catch (Exception e) {
								logger.error("getAttach方法关闭附件IO流异常！", e);
								throw new IOException("getAttach方法关闭附件IO流异常！");
							}
						}
					}
				}
			}
		}
		return attachmentList;
	}

	// 此方法已不用
	public static void createCms(Map<String, Object> params, String refBoName, String refBoId, String refBindid,
			String acValue) {
		ResponseObject ro = SDK.getAppAPI().callASLP(SDK.getAppAPI().getAppContext(sourceAppId), aslp, params);
		ConsolePrinter.info("赋CMS权限返回值-----" + ro.toString());
		ConsolePrinter.info("赋CMS权限返回值-----" + ro.toString());
		if (ro != null && ro.isOk()) {
			List<String> action = new ArrayList<String>();
			ProcessInstance pInstance = SDK.getProcessQueryAPI().detailById(refBindid);
			if (pInstance.isExistSubProcess()) {
				List<ProcessInstance> sublist = SDK.getProcessQueryAPI().parentProcessInstId(refBindid).list();
				for (ProcessInstance pi : sublist) {
					List<HistoryTaskInstance> subtaskInstances = SDK.getHistoryTaskQueryAPI().processInstId(pi.getId())
							.userTask().list();
					for (HistoryTaskInstance ht : subtaskInstances) {
						if (!action.contains(ht.getTarget())) {
							action.add(ht.getTarget());
						}
					}
				}
			}
			List<HistoryTaskInstance> taskInstances = SDK.getHistoryTaskQueryAPI().processInstId(refBindid).userTask().list();
			for (HistoryTaskInstance ht : taskInstances) {
				if (!action.contains(ht.getTarget())) {
					action.add(ht.getTarget());
				}
			}

			action.add("admin");
			String cmsBoId = ro.get("boId") + "";
			ConsolePrinter.info("特殊授权数组----" + action.toArray().toString());
			String[] acs = new String[action.size()];
			for (int i = 0; i < action.size(); i++) {
				acs[i] = action.get(i);
			}
			addCMSPermi(cmsBoId, acs, ACConst.ASSIGN_USER);
		}
	}

	public static void addCMSPermi(String cmsBoId, List<String> acList, String acType) {
		if (CollectionUtils.isNotEmpty(acList)) {
			for (String ac : acList) {
				SDK.getPermAPI().appendACResource(cmsBoId, "platform.process", 0, ac, acType);
			}
		}
	}

	public static void addCMSPermi(String cmsBoId, String[] acs, String acType) {
		if (acs != null && acs.length > 0) {
			for (String ac : acs) {
				SDK.getPermAPI().appendACResource(cmsBoId, "platform.process", 0, ac, acType);
			}
		}
	}

	private void upCmsFile(String cmsBoId, String refBoId) {
		// 上传附件
		List<FormFile> formFileList = SDK.getBOAPI().getFiles(refBoId, "ZW");
		if (formFileList != null && !formFileList.isEmpty() && formFileList.size() > 0) {
			FormFile formFile = formFileList.get(0);
			if (formFile != null) {
				InputStream is = null;
				try {
					DCContext contentDc = new DCContext(UserContext.fromUID("admin"),
							DCProfileManager.getDCProfile(formFile.getAppId(), "!iweboffice-"), formFile.getAppId(),
							formFile.getProcessInstId(), formFile.getBoItemName(), formFile.getFileName());
					if (contentDc != null) {
						is = SDK.getDCAPI().read(contentDc);
					}
					BO cmsBo = SDK.getBOAPI().get("BO_ACT_CMS_CONTENT", cmsBoId);
					// 将该附件上传至cms上
					FormFileModel fm = new FormFileModel();
					fm.setAppId("com.actionsoft.apps.cms");
					fm.setCreateDate(new Timestamp(System.currentTimeMillis()));
					fm.setCreateUser("admin");
					fm.setId(UUIDGener.getUUID());
					fm.setBoId(cmsBoId);
					fm.setBoName("BO_ACT_CMS_CONTENT");
					fm.setFileName(formFile.getFileName());
					fm.setBoItemName("ATTACHMENT");
					fm.setProcessInstId(cmsBo.getBindId());
					SDK.getBOAPI().upFile(fm, is);
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						is.close();
					} catch (Exception e) {

					}
				}

			}
		}
	}
}
